<!DOCTYPE html>
<html CN>







<head>
	
	
	<link rel="stylesheet" href="/css/allinone.min.css"> 

	
	<!-- Global Site Tag (gtag.js) - Google Analytics -->
	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-42863699-1"></script>
	<script>
		window.dataLayer = window.dataLayer || [];
		function gtag(){dataLayer.push(arguments);}
		gtag('js', new Date());
		gtag('config', 'UA-42863699-1');
	</script>
	

	<meta charset="utf-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />

	<title>kubernetes 权限管理 | Cizixs Write Here</title>

	<meta name="HandheldFriendly" content="True" />
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
	<meta name="generator" content="hexo">
	<meta name="author" content="Cizixs Wu">
	<meta name="description" content="">

	
	<meta name="keywords" content="">
	

	
	<link rel="shortcut icon" href="https://cizixs-blog.oss-cn-beijing.aliyuncs.com/006tNc79ly1g1qxfovpzyj30740743yg.jpg">
	

	
	<meta name="theme-color" content="#3c484e">
	<meta name="msapplication-TileColor" content="#3c484e">
	

	

	

	<meta property="og:site_name" content="Cizixs Write Here">
	<meta property="og:type" content="article">
	<meta property="og:title" content="kubernetes 权限管理 | Cizixs Write Here">
	<meta property="og:description" content="">
	<meta property="og:url" content="http://cizixs.com/2017/06/16/kubernetes-authentication-and-authorization/">

	
	<meta property="article:published_time" content="2017-06-16T00:06:00+08:00"/> 
	<meta property="article:author" content="Cizixs Wu">
	<meta property="article:published_first" content="Cizixs Write Here, /2017/06/16/kubernetes-authentication-and-authorization/" />
	

	
	
	<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
	

	
	<script src="https://cdn.staticfile.org/highlight.js/9.10.0/highlight.min.js"></script>
	

	
	
<link rel="stylesheet" href="/css/prism-base16-ateliersulphurpool.light.css" type="text/css"></head>
<body class="post-template">
    <div class="site-wrapper">
        




<header class="site-header outer" style="z-index: 999">
    <div class="inner">
        
<nav class="site-nav"> 
    <div class="site-nav-left">
        <ul class="nav">
            <li>
                
                <a href="/" title="Home">Home</a>
                
            </li>
            
            
            <li>
                <a href="/about" title="About">About</a>
            </li>
            
            <li>
                <a href="/archives" title="Archives">Archives</a>
            </li>
            
            
        </ul> 
    </div>
    <div class="site-nav-right">
        
<div class="social-links" >
    
    <a class="social-link" title="weibo" href="https://weibo.com/1921727853" target="_blank" rel="noopener">
        <svg viewBox="0 0 1141 1024" xmlns="http://www.w3.org/2000/svg"><path d="M916.48 518.144q27.648 21.504 38.912 51.712t9.216 62.976-14.336 65.536-31.744 59.392q-34.816 48.128-78.848 81.92t-91.136 56.32-94.72 35.328-89.6 18.944-75.264 7.68-51.712 1.536-49.152-2.56-68.096-10.24-78.336-21.504-79.872-36.352-74.24-55.296-59.904-78.848q-16.384-29.696-22.016-63.488t-5.632-86.016q0-22.528 7.68-51.2t27.136-63.488 53.248-75.776 86.016-90.112q51.2-48.128 105.984-85.504t117.248-57.856q28.672-10.24 63.488-11.264t57.344 11.264q10.24 11.264 19.456 23.04t12.288 29.184q3.072 14.336 0.512 27.648t-5.632 26.624-5.12 25.6 2.048 22.528q17.408 2.048 33.792-1.536t31.744-9.216 31.232-11.776 33.28-9.216q27.648-5.12 54.784-4.608t49.152 7.68 36.352 22.016 17.408 38.4q2.048 14.336-2.048 26.624t-8.704 23.04-7.168 22.016 1.536 23.552q3.072 7.168 14.848 13.312t27.136 12.288 32.256 13.312 29.184 16.384zM658.432 836.608q26.624-16.384 53.76-45.056t44.032-64 18.944-75.776-20.48-81.408q-19.456-33.792-47.616-57.344t-62.976-37.376-74.24-19.968-80.384-6.144q-78.848 0-139.776 16.384t-105.472 43.008-72.192 60.416-38.912 68.608q-11.264 33.792-6.656 67.072t20.992 62.976 42.496 53.248 57.856 37.888q58.368 25.6 119.296 32.256t116.224 0.512 100.864-21.504 74.24-33.792zM524.288 513.024q20.48 8.192 38.912 18.432t32.768 27.648q10.24 12.288 17.92 30.72t10.752 39.424 1.536 42.496-9.728 38.912q-8.192 18.432-19.968 37.376t-28.672 35.328-40.448 29.184-57.344 18.944q-61.44 11.264-117.76-11.264t-88.064-74.752q-12.288-39.936-13.312-70.656t16.384-66.56q13.312-27.648 40.448-51.712t62.464-38.912 75.264-17.408 78.848 12.8zM361.472 764.928q37.888 3.072 57.856-18.432t21.504-48.128-15.36-47.616-52.736-16.896q-27.648 3.072-43.008 23.552t-17.408 43.52 9.728 42.496 39.424 21.504zM780.288 6.144q74.752 0 139.776 19.968t113.664 57.856 76.288 92.16 27.648 122.88q0 33.792-16.384 50.688t-35.328 17.408-35.328-14.336-16.384-45.568q0-40.96-22.528-77.824t-59.392-64.512-84.48-43.52-96.768-15.872q-31.744 0-47.104-15.36t-14.336-34.304 18.944-34.304 51.712-15.36zM780.288 169.984q95.232 0 144.384 48.64t49.152 146.944q0 30.72-10.24 43.52t-22.528 11.264-22.528-14.848-10.24-35.84q0-60.416-34.816-96.256t-93.184-35.84q-19.456 0-28.672-10.752t-9.216-23.04 9.728-23.04 28.16-10.752z" /></svg>
    </a>
    

    
    <a class="social-link" title="github" href="https://github.com/cizixs" target="_blank" rel="noopener">
        <svg viewBox="0 0 1049 1024" xmlns="http://www.w3.org/2000/svg"><path d="M524.979332 0C234.676191 0 0 234.676191 0 524.979332c0 232.068678 150.366597 428.501342 358.967656 498.035028 26.075132 5.215026 35.636014-11.299224 35.636014-25.205961 0-12.168395-0.869171-53.888607-0.869171-97.347161-146.020741 31.290159-176.441729-62.580318-176.441729-62.580318-23.467619-60.841976-58.234462-76.487055-58.234463-76.487055-47.804409-32.15933 3.476684-32.15933 3.476685-32.15933 53.019436 3.476684 80.83291 53.888607 80.83291 53.888607 46.935238 79.963739 122.553122 57.365291 152.97411 43.458554 4.345855-33.897672 18.252593-57.365291 33.028501-70.402857-116.468925-12.168395-239.022047-57.365291-239.022047-259.012982 0-57.365291 20.860106-104.300529 53.888607-140.805715-5.215026-13.037566-23.467619-66.926173 5.215027-139.067372 0 0 44.327725-13.906737 144.282399 53.888607 41.720212-11.299224 86.917108-17.383422 131.244833-17.383422s89.524621 6.084198 131.244833 17.383422C756.178839 203.386032 800.506564 217.29277 800.506564 217.29277c28.682646 72.1412 10.430053 126.029806 5.215026 139.067372 33.897672 36.505185 53.888607 83.440424 53.888607 140.805715 0 201.64769-122.553122 245.975415-239.891218 259.012982 19.121764 16.514251 35.636014 47.804409 35.636015 97.347161 0 70.402857-0.869171 126.898978-0.869172 144.282399 0 13.906737 9.560882 30.420988 35.636015 25.205961 208.601059-69.533686 358.967656-265.96635 358.967655-498.035028C1049.958663 234.676191 814.413301 0 524.979332 0z" /></svg>
    </a>
    

    
    <a class="social-link" title="stackoverflow" href="https://stackoverflow.com/users/1925083/cizixs" target="_blank" rel="noopener">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15 21h-10v-2h10v2zm6-11.665l-1.621-9.335-1.993.346 1.62 9.335 1.994-.346zm-5.964 6.937l-9.746-.975-.186 2.016 9.755.879.177-1.92zm.538-2.587l-9.276-2.608-.526 1.954 9.306 2.5.496-1.846zm1.204-2.413l-8.297-4.864-1.029 1.743 8.298 4.865 1.028-1.744zm1.866-1.467l-5.339-7.829-1.672 1.14 5.339 7.829 1.672-1.14zm-2.644 4.195v8h-12v-8h-2v10h16v-10h-2z"/></svg>
    </a>
    

    

    
    <a class="social-link" title="twitter" href="https://twitter.com/cizixs" target="_blank" rel="noopener">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"/></svg>

    </a>
    

    
    <a class="social-link" title="instagram" href="https://www.instagram.com/cizixs/" target="_blank" rel="noopener">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/></svg>
    </a>
    
    
    
</div>
    </div>
</nav>
    </div>
</header>


<main id="site-main" class="site-main outer" role="main">
    <div class="inner">
        <header class="post-full-header">
            <section class="post-full-meta">
                <time  class="post-full-meta-date" datetime="2017-06-15T16:00:00.000Z" itemprop="datePublished">
                    2017-06-16
                </time>
                
                <span class="date-divider">/</span>
                
                <a href="/categories/blog/">blog</a>&nbsp;&nbsp;
                
                
            </section>
            <h1 class="post-full-title">kubernetes 权限管理</h1>
        </header>
        <article class="post-full no-image">
            
            <section class="post-full-content">
                <div id="lightgallery" class="markdown-body">
                    <p>kubernetes 主要通过 APIServer 对外提供服务，对于这样的系统集群来说，请求访问的安全性是非常重要的考虑因素。如果不对请求加以限制，那么会导致请求被滥用，甚至被黑客攻击。</p>
<p>kubernetes 对于访问 API 来说提供了两个步骤的安全措施：认证和授权。认证解决用户是谁的问题，授权解决用户能做什么的问题。通过合理的权限管理，能够保证系统的安全可靠。</p>
<p>下图是 API 访问要经过的三个步骤，前面两个是认证和授权，第三个是 Admission Control，它也能在一定程度上提高安全性，不过更多是资源管理方面的作用，在这篇文章不会介绍。</p>
<p><img src="https://kubernetes.io/images/docs/admin/access-control-overview.svg" alt=""></p>
<p><strong>NOTE</strong>： 只有通过 HTTPS 访问的时候才会通过认证和授权，HTTP 不需要。</p>
<h2 id="一-认证（Authentication）：我是谁"><a href="#一-认证（Authentication）：我是谁" class="headerlink" title="一. 认证（Authentication）：我是谁"></a>一. 认证（Authentication）：我是谁</h2><p>认证关注的是谁发送的请求，也就是说客户端必须用某种方式揭示自己的身份信息。我们常见的认证手段是用户名和密码的方法，比如几乎所有的社交网站；现在也有很多手机应用采用指纹的方式进行认证。不管怎么说，认证的功能只有一个，提供用户的身份信息。</p>
<p>kubernetes 并没有完整的用户系统，因此目前认证的方式并不是统一的，而是提供了很多可以配置的认证方式供用户选择。这些认证方式包括：</p>
<h3 id="客户端证书认证"><a href="#客户端证书认证" class="headerlink" title="客户端证书认证"></a>客户端证书认证</h3><p>我们知道，一般在访问服务端的时候为了安全考虑会采用 HTTPS 的方式。但其实 HTTPS 连接可以是双向的，也就是说客户端也可以提供证书给服务端。kubernetes 可以使用客户端证书来作为认证，X509 HTTPS 的证书中会包含证书所有者的身份信息，就是证书中的 <code>Common Name</code> 字段。apiserver 启动的时候通过参数 <code>--client-ca-file=SOMEFILE</code> 来配置签发客户端证书的 CA，当客户端发送证书过来的时候，apiserver 会使用 CA 进行验证，如果证书合法，就提取其中的 <code>Common Name</code> 字段作为用户名。</p>
<p>NOTE：关于 HTTPS、CA、证书的内容的解释超过了这篇文章的范围，感兴趣的读者可以自行搜索对应的资料了解。</p>
<h3 id="静态密码文件认证"><a href="#静态密码文件认证" class="headerlink" title="静态密码文件认证"></a>静态密码文件认证</h3><p>静态密码的方式是提前在某个文件中保存了用户名和密码的信息，然后在 apiserver 启动的时候通过参数 <code>--basic-auth-file=SOMEFILE</code> 指定文件的路径。apiserver 一旦启动，加载的用户名和密码信息就不会发生改变，任何对源文件的修改必须重启 apiserver 才能生效。</p>
<p>静态密码文件是 CSV 格式的文件，每行对应一个用户的信息，前面三列密码、用户名、用户 ID 是必须的，第四列是可选的组名（如果有多个组，必须用双引号）：</p>
<pre><code>password,user,uid,&quot;group1,group2,group3&quot;
</code></pre><p>客户端在发送请求的时候需要在请求头部添加上 <code>Authorization</code> 字段，对应的值是 <code>Basic BASE64ENCODED(USER:PASSWORD)</code>。apiserver 解析出客户端提供的用户名和密码，如果和文件中的某一行匹配，就认为认证成功。</p>
<p><strong>NOTE</strong>：这种方式很不灵活，也不安全，可以说名存实亡，不推荐使用。</p>
<h3 id="静态-Token-文件认证"><a href="#静态-Token-文件认证" class="headerlink" title="静态 Token 文件认证"></a>静态 Token 文件认证</h3><p>静态 Token 文件的方式很简单，事先在一个文件中写上用户的认证信息（用户名、用户 id、token、用户所在的组名），apiserver 启动通过参数 <code>--token-auth-file=SOMEFILE</code> 指定这个文件，apiserver 把这些信息加载起来。token 文件是 CSV 格式的文件，每行代表一个用户的信息，至少包含 token、用户名和用户 ID 三列，最后一列组名列表是可选的（如果有多个组必须用双引号括起来），比如：</p>
<pre><code>token,user,uid,&quot;group1,group2,group3&quot;
</code></pre><p>token 有点像令牌，客户端不需要证明自己和 token 的关系，只要客户端提供了令牌，就认为客户端身份是合法的。这有点像古装剧中拿着皇上颁发的某个令牌行事，不管谁拿着令牌都有对应的权力。</p>
<p>客户端只要在请求的头部加上 <code>Authorization</code> 字段就能完成认证，对应的值是 <code>Bearer TOKEN</code>。</p>
<p>这种方式下，apiserver 一旦启动就不会再根据文件的内容调整内存中的数据，想要让修改的文件生效，只能重启 apiserver。<strong>和静态密码一样，这种方法也是名存实亡，不推荐使用。</strong></p>
<p>如果配置了多个认证方式，kubernetes 会以此遍历它们（并不保证它们的先后顺序），一旦请求能通过某个认证，就算成功。</p>
<h3 id="Service-Account-Tokens-认证"><a href="#Service-Account-Tokens-认证" class="headerlink" title="Service Account Tokens 认证"></a>Service Account Tokens 认证</h3><p>有些情况下，我们希望在 pod 内部访问 apiserver，获取集群的信息，甚至对集群进行改动。针对这种情况，kubernetes 提供了一种特殊的认证方式：Service Account。</p>
<p>Service Account 是面向 namespace 的，每个 namespace 创建的时候，kubernetes 会自动在这个 namespace 下面创建一个默认的 Service Account；并且这个 Service Account 只能访问该 namespace 的资源。Service Account 和 pod、service、deployment 一样是 kubernetes 集群中的一种资源，用户也可以创建自己的 serviceaccount。</p>
<p>ServiceAccount 主要包含了三个内容：namespace、Token 和 CA。namespace 指定了 pod 所在的 namespace，CA 用于验证 apiserver 的证书，token 用作身份验证。它们都通过 mount 的方式保存在 pod 的文件系统中，其中 <code>token</code> 保存的路径是 <code>/var/run/secrets/kubernetes.io/serviceaccount/token</code>，是 apiserver 通过私钥签发 token 的 base64 编码后的结果；<code>CA</code> 保存的路径是 <code>/var/run/secrets/kubernetes.io/serviceaccount/ca.crt</code>，namespace 保存的路径是 <code>/var/run/secrets/kubernetes.io/serviceaccount/namespace</code>，也是用 base64 编码。</p>
<p>如果 token 能够通过认证，那么请求的用户名将被设置为 <code>system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)</code>，而请求的组名有两个：<code>system:serviceaccounts</code> 和 <code>system:serviceaccounts:(NAMESPACE)</code>。</p>
<p>关于 Service Account 的配置可以参考官方的 <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/" target="_blank" rel="noopener">Configure Service Accounts for Pods</a> 文档。</p>
<h3 id="OpenID-认证"><a href="#OpenID-认证" class="headerlink" title="OpenID 认证"></a>OpenID 认证</h3><p>这种认证方式是通过 OAuth2 协议进行的，也就是第三方登录常用的方式。因为没有使用过，略过不表，感兴趣可以参考 OAuth2 的原理。</p>
<h3 id="Webhook-Token-认证"><a href="#Webhook-Token-认证" class="headerlink" title="Webhook Token 认证"></a>Webhook Token 认证</h3><p>Webhook Token 认证方式可以让用户使用自己的认证方式，用户只需要按照约定的请求格式和应答格式提供 HTTPS 服务，当用户把 Bearer Token 放到请求的头部，kubernetes 会把 token 发送给事先配置的地址进行认证，如果认证结果成功，则认为请求用户合法。</p>
<p>这种方式下有两个参数可以配置：</p>
<ul>
<li><code>--authentication-token-webhook-config-file</code>：kubeconfig 文件说明如果访问认证服务器</li>
<li><code>--authentication-token-webhook-cache-ttl</code>：认证结果要缓存多久，默认是两分钟</li>
</ul>
<p>这种方式下，自定义认证的请求和应答都有一定的格式，具体的规范请参考<a href="https://kubernetes.io/docs/admin/authentication/#webhook-token-authentication" target="_blank" rel="noopener">官方文档的说明</a>。</p>
<h3 id="Keystone-认证"><a href="#Keystone-认证" class="headerlink" title="Keystone 认证"></a>Keystone 认证</h3><p><a href="http://docs.openstack.org/developer/keystone/" target="_blank" rel="noopener">Keystone</a> 是 openstack 提供的认证和授权组件，这个方法对于已经使用 openstack 来搭建 Iaas 平台的公司比较适用，直接使用 keystone 可以保证 Iaas 和 Caas 平台保持一致的用户体系。</p>
<p>kubernetes 目前对 keystone 的支持还是实验阶段，不推荐在生产系统中使用。</p>
<h3 id="匿名请求"><a href="#匿名请求" class="headerlink" title="匿名请求"></a>匿名请求</h3><p>如果请求没有通过以上任何方式的认证，正常情况下应该是直接返回 401 错误。但是 kubernetes 还提供另外一种选择，给没有通过认证的请求一个特殊的用户名 <code>system:anonymous</code> 和组名 <code>system:unauthenticated</code>。</p>
<p>这样的话，可以跟下面要讲的授权结合起来，为匿名请求设置一些特殊的权限，比如只能读取当前 namespace 的 pod 信息，方便用户访问。</p>
<h2 id="二-授权（Authorization）：我能做什么"><a href="#二-授权（Authorization）：我能做什么" class="headerlink" title="二. 授权（Authorization）：我能做什么"></a>二. 授权（Authorization）：我能做什么</h2><p>授权发生在认证之后，通过认证的请求就能知道 username，而授权判断这个用户是否有权限对访问的资源执行特定的动作。</p>
<p>还是拿社交软件做例子，当用户成功登录之后，他能操作的资源范围是固定的：查看和自己有关系的用户的数据，但是只能修改自己的数据。不难想象，你可以随意地删除或者修改其他用户的信息是一件多么恐怖的事情。</p>
<p>在系统软件中，用户还分成不同的角色，最常见的比如管理员。如果普通用户只能看到自己视角内的内容，那么管理员的权限则大得多，它一般能查看整个系统的数据，并且能对大部分内容做修改（包括删除）。</p>
<p><strong>控制不同用户能操作哪些内容就是授权要做的事情</strong>。</p>
<p>在启动 apiserver 的时候，可以通过 <code>--authorization_mode</code> 参数来指定授权模式，目前支持的模式有：</p>
<ul>
<li><code>AlwaysDeny</code>：阻止所有的请求访问，只用于测试环境</li>
<li><code>AlwaysAllow</code>：允许所有的请求访问，注意这个模式下没有对请求进行限制，只有你能确保没有恶意请求的时候使用</li>
<li><code>ABAC</code>：基于属性的访问控制</li>
<li><code>RBAC</code>：基于角色的访问控制，这是 1.6 版本之后开始推荐的授权方式</li>
<li><code>WebHook</code>：</li>
</ul>
<p>kubernetes apiserver 根据事先定义的授权策略 来决定用户是否有权限访问。每个请求都带上了用户和资源的信息：比如发送请求的用户、请求的路径、请求的动作等，授权就是根据这些信息和授权策略进行比较，如果符合策略，则认为授权通过，否则会返回 <code>403 Unauthorized</code> 错误。</p>
<p>和认证一样，管理员可以配置多个授权方式，一种任何一种方式通过，就认为授权成功。所以如果配置了 <code>AlwaysAllow</code>，不管还配置了什么，请求都能直接通过授权。</p>
<p>kubernetes 把请求分成了两种：资源请求和非资源请求。资源请求是对 kubernetes 封装的资源实体的请求，比如 pods、nodes、services 等；非资源请求相反，是对诸如 <code>/api</code>、<code>/metrics</code>、<code>healthz</code> 等和资源无关的请求。它们两者的授权也有区别。</p>
<p><code>AlwaysAllow</code> 和 <code>AlwaysDeny</code> 比较简单，我们就不介绍了，而是看看其他三种方法。</p>
<h3 id="ABAC（Attribute-Based-Access-Control）"><a href="#ABAC（Attribute-Based-Access-Control）" class="headerlink" title="ABAC（Attribute-Based Access Control）"></a>ABAC（Attribute-Based Access Control）</h3><p>ABAC 根据请求的属性来决定某个请求是否有权限，授权策略是写到文件中的，因此如果配置了该方法，apiserver 在启动的时候还要通过参数 <code>--authorization-policy-file=SOME_FILENAME</code> 告诉策略文件的位置。</p>
<p>这个文件每行定义了一个策略，每个策略都是 JSON 格式的内容。这个 JSON 可以包含如下的内容：</p>
<ul>
<li><code>apiVersion</code>：版本号，目前是 <code>abac.authorization.kubernetes.io/v1beta1</code></li>
<li><code>kind</code>：资源类型，必须是 <code>Policy</code></li>
<li><code>spec</code>：具体的策略配置，这是个字典，包括这些字段：<ul>
<li><code>user</code>：用户名</li>
<li><code>group</code>：组名。<code>system:authenticated</code> 匹配所有通过认证的请求，<code>system:unauthenticated</code> 匹配所有没有通过认证的请求</li>
<li><code>apiGroup</code>：资源的 API group，比如 <code>extensions</code>，<code>*</code> 表示匹配所有的 API group</li>
<li><code>namespace</code>：kubernetes 中的 namespace，比如 <code>kube-system</code>，<code>*</code> 匹配所有的 namespace</li>
<li><code>resource</code>：资源类型，比如 <code>pods</code>，<code>*</code> 匹配所有的资源类型</li>
<li><code>nonResourcePath</code>：非资源请求的路径，比如 <code>/version</code>或者 <code>/apis</code> 等，<code>*</code> 匹配所有的非资源路径，<code>/foo/*</code> 匹配所有 <code>/foo</code> 的子路径</li>
<li><code>readonly</code>：布尔型，是否只读，默认为 false。如果设置为 true，则用户只有 GET、LIST 和 WATCH 权限</li>
</ul>
</li>
</ul>
<p>每个请求都有对应的属性，授权的时候会一次匹配所有的规则，如果有某个规则匹配，则认为请求有对应的权限（Read/Write）。可以看到，通配符 <code>*</code> 表示匹配任意的值，比如可以让某个用户可以访问任意资源。</p>
<p>来看几个例子：</p>
<h4 id="1-Alice-可以做任何事情"><a href="#1-Alice-可以做任何事情" class="headerlink" title="1. Alice 可以做任何事情"></a>1. Alice 可以做任何事情</h4><pre><code>{&quot;apiVersion&quot;: &quot;abac.authorization.kubernetes.io/v1beta1&quot;, &quot;kind&quot;: &quot;Policy&quot;, &quot;spec&quot;: {&quot;user&quot;: &quot;alice&quot;, &quot;namespace&quot;: &quot;*&quot;, &quot;resource&quot;: &quot;*&quot;, &quot;apiGroup&quot;: &quot;*&quot;}}
</code></pre><h4 id="2-kubelet-可以读取所有-pods-的信息"><a href="#2-kubelet-可以读取所有-pods-的信息" class="headerlink" title="2. kubelet 可以读取所有 pods 的信息"></a>2. kubelet 可以读取所有 pods 的信息</h4><pre><code>{&quot;apiVersion&quot;: &quot;abac.authorization.kubernetes.io/v1beta1&quot;, &quot;kind&quot;: &quot;Policy&quot;, &quot;spec&quot;: {&quot;user&quot;: &quot;kubelet&quot;, &quot;namespace&quot;: &quot;*&quot;, &quot;resource&quot;: &quot;pods&quot;, &quot;readonly&quot;: true}}
</code></pre><h4 id="3-kubelet-可以对-events-进行任何的读写操作"><a href="#3-kubelet-可以对-events-进行任何的读写操作" class="headerlink" title="3. kubelet 可以对 events 进行任何的读写操作"></a>3. kubelet 可以对 events 进行任何的读写操作</h4><pre><code>{&quot;apiVersion&quot;: &quot;abac.authorization.kubernetes.io/v1beta1&quot;, &quot;kind&quot;: &quot;Policy&quot;, &quot;spec&quot;: {&quot;user&quot;: &quot;kubelet&quot;, &quot;namespace&quot;: &quot;*&quot;, &quot;resource&quot;: &quot;events&quot;}}
</code></pre><h4 id="4-Bob-可以读取-projectCaribou-namespace-的所有-pods-信息"><a href="#4-Bob-可以读取-projectCaribou-namespace-的所有-pods-信息" class="headerlink" title="4. Bob 可以读取 projectCaribou namespace 的所有 pods 信息"></a>4. Bob 可以读取 <code>projectCaribou</code> namespace 的所有 pods 信息</h4><pre><code>{&quot;apiVersion&quot;: &quot;abac.authorization.kubernetes.io/v1beta1&quot;, &quot;kind&quot;: &quot;Policy&quot;, &quot;spec&quot;: {&quot;user&quot;: &quot;bob&quot;, &quot;namespace&quot;: &quot;projectCaribou&quot;, &quot;resource&quot;: &quot;pods&quot;, &quot;readonly&quot;: true}}
</code></pre><h4 id="5-所有人都能对所有路径发送只读请求"><a href="#5-所有人都能对所有路径发送只读请求" class="headerlink" title="5. 所有人都能对所有路径发送只读请求"></a>5. 所有人都能对所有路径发送只读请求</h4><pre><code>{&quot;apiVersion&quot;: &quot;abac.authorization.kubernetes.io/v1beta1&quot;, &quot;kind&quot;: &quot;Policy&quot;, &quot;spec&quot;: {&quot;group&quot;: &quot;system:authenticated&quot;, &quot;readonly&quot;: true, &quot;nonResourcePath&quot;: &quot;*&quot;}}
{&quot;apiVersion&quot;: &quot;abac.authorization.kubernetes.io/v1beta1&quot;, &quot;kind&quot;: &quot;Policy&quot;, &quot;spec&quot;: {&quot;group&quot;: &quot;system:unauthenticated&quot;, &quot;readonly&quot;: true, &quot;nonResourcePath&quot;: &quot;*&quot;}}
</code></pre><p><strong>NOTE</strong>：ABAC 对权限的定义比较少，只有可读、可读写两种。并且策略修改后只有重启 apiserver 才能生效，因此用起来不是很方便。</p>
<h3 id="RBAC（Role-Based-Access-Control）"><a href="#RBAC（Role-Based-Access-Control）" class="headerlink" title="RBAC（Role-Based Access Control）"></a>RBAC（Role-Based Access Control）</h3><p>RBAC 是官方才 1.6 版本之后推荐使用的授权方式，因为它比较灵活，而且能够很好地实现资源隔离效果。</p>
<p>这种方法引入了一个重要的概念：Role，翻译成角色。所有的权限都是围绕角色进行的，也就是说角色本身会包含一系列的权限规则，表明某个角色能做哪些事情。比如管理员可以操作所有的资源，某个 namespace 的用户只能修改该 namespace的内容，或者有些角色只允许读取资源。角色和 pods、services 这些资源一样，可以通过 API 创建和删除，因此用户可以非常灵活地根据需求创建角色。</p>
<p>RBAC 定义了 <code>Role</code> 和 <code>ClusterRole</code>，分别对应单个 namespace 的权限和整个集群的权限，来对两者进行区分。</p>
<p>权限就是对某个资源可以执行什么样的操作，操作可以是 <code>get</code>、<code>list</code>、<code>watch</code>、<code>create</code>、<code>update</code>、<code>patch</code> 和 <code>delete</code>，因此粒度要比 ABAC 更细，资源就对应了 kubernetes API 管理的资源概念，比如：</p>
<pre><code>rules:
- apiGroups: [&quot;&quot;]
  resources: [&quot;pods&quot;]
  verbs: [&quot;get&quot;, &quot;list&quot;, &quot;watch&quot;]
- apiGroups: [&quot;batch&quot;, &quot;extensions&quot;]
  resources: [&quot;jobs&quot;]
  verbs: [&quot;get&quot;, &quot;list&quot;, &quot;watch&quot;, &quot;create&quot;, &quot;update&quot;, &quot;patch&quot;, &quot;delete&quot;]
</code></pre><p>上面定义了两个权限，分别是读取 pods 和读写 jobs 资源。</p>
<p>有了权限之后，最终还是要对应到用户上面，用户和角色之间可以进行绑定，绑定后的用户就能拥有对应角色的所有权限。比如我们可以添加一个管理员角色，然后把公司的某几个人设置（绑定）成管理员。一个用户可以和多个角色进行绑定，同时应用这些角色的权限。</p>
<p>和 Role 一样，RBAC 也有两种资源：<code>RoleBinding</code> 和 <code>ClusterRoleBinding</code>，分别对应单个 namespace 和整个集群范围。</p>
<p>我们来看个例子：</p>
<pre><code>kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
</code></pre><p>这个 RoleBinding 就是把用户 <code>jane</code> 绑定到 <code>pod-reader</code> 这个角色。</p>
<p>以上就是 RBAC 最核心的概念，还有什么细节没有讲，比如怎么具体去指定某个资源/子资源、怎么做授权、ClusterRole 的一些边缘特性、kubernetes 预先创建的一些默认角色和绑定等等。RBAC 相对 ABAC 概念更多，也更复杂，想看具体的例子和更多 RBAC 的内容，可以参考<a href="https://kubernetes.io/docs/admin/authorization/rbac/" target="_blank" rel="noopener">官方文档</a>。</p>
<h3 id="Web-Hook"><a href="#Web-Hook" class="headerlink" title="Web Hook"></a>Web Hook</h3><p>这里的 webhook 和验证差不多，就是用户在外部提供 HTTPS 服务，然后配置 apiserver 调用该服务去进行授权，略过不提。</p>
<h3 id="自定义"><a href="#自定义" class="headerlink" title="自定义"></a>自定义</h3><p>除了上面两个方式之外，用户也可以自己直接修改 kubernetes 代码，编写授权方式。因为 kubernetes 做了很好的封装，用户只需要实现下面的接口即可：</p>
<pre><code>type Authorizer interface {
  Authorize(a Attributes) error
}
</code></pre><p>把自己编写的代码放在 <code>pkg/auth/authorizer/$MODULENAME</code> 路径就行。</p>
<h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul>
<li><a href="https://kubernetes.io/docs/admin/accessing-the-api/" target="_blank" rel="noopener">Controlling Access to the Kubernetes API：和 kubernetes API 通信的流程</a></li>
<li><a href="https://kubernetes.io/docs/admin/authentication/" target="_blank" rel="noopener">Authenticating：kubernetes 认证机制</a></li>
<li><a href="https://kubernetes.io/docs/admin/authorization/" target="_blank" rel="noopener">Authorization：kubernetes 授权机制</a></li>
<li><a href="https://kubernetes.io/docs/admin/admission-controllers/" target="_blank" rel="noopener">Using Admission Controllers</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/26220963" target="_blank" rel="noopener">容器编排之Kubernetes认证与授权</a></li>
<li><a href="http://cloudgeekz.com/1045/kubernetes-authentication-and-authorization.html" target="_blank" rel="noopener">Understanding Kubernetes Authentication and Authorization</a></li>
<li><a href="https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod" target="_blank" rel="noopener">Accessing the API from a Pod</a></li>
<li><a href="http://tonybai.com/2017/03/03/access-api-server-from-a-pod-through-serviceaccount/" target="_blank" rel="noopener">在Kubernetes Pod中使用Service Account访问API Server</a></li>
<li><a href="http://tonybai.com/2016/11/25/the-security-settings-for-kubernetes-cluster/" target="_blank" rel="noopener">Kubernetes集群的安全配置</a></li>
<li><a href="http://www.sel.zju.edu.cn/?p=588" target="_blank" rel="noopener">4S: SERVICES ACCOUNT, SECRET, SECURITY CONTEXT AND SECURITY IN KUBERNETES</a></li>
</ul>

                </div>
            </section>
        </article>
    </div>
    
<nav class="pagination">
    
    
    <a class="prev-post" title="kubelet 源码分析： 事件处理" href="/2017/06/22/kubelet-source-code-analysis-part4-event/">
        ← kubelet 源码分析： 事件处理
    </a>
    
    <span class="prev-next-post">•</span>
    
    <a class="next-post" title="kubelet 源码分析：statusManager 和 probeManager" href="/2017/06/12/kubelet-source-code-analysis-part4-status-manager/">
        kubelet 源码分析：statusManager 和 probeManager →
    </a>
    
    
</nav>

    <div class="inner">
    <!-- Begin Mailchimp Signup Form -->
    <link href="//cdn-images.mailchimp.com/embedcode/classic-10_7.css" rel="stylesheet" type="text/css">
    <style type="text/css">
    	#mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
    	/* Add your own Mailchimp form style overrides in your site stylesheet or in this style block.
    	   We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
    </style>
    <div id="mc_embed_signup">
    <form action="https://cizixs.us7.list-manage.com/subscribe/post?u=2d561b8dea52d73a2e05e6dcb&amp;id=5c710f135b" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
        <div id="mc_embed_signup_scroll">
    	<h2>订阅本博客，第一时间收到文章更新</h2>
    <div class="indicates-required"><span class="asterisk">*</span> indicates required</div>
    <div class="mc-field-group">
    	<label for="mce-EMAIL">邮件地址  <span class="asterisk">*</span>
    </label>
    	<input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
    </div>
    	<div id="mce-responses" class="clear">
    		<div class="response" id="mce-error-response" style="display:none"></div>
    		<div class="response" id="mce-success-response" style="display:none"></div>
    	</div>    <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
        <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_2d561b8dea52d73a2e05e6dcb_5c710f135b" tabindex="-1" value=""></div>
        <div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
        </div>
    </form>
    </div>
    <script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script><script type='text/javascript'>(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';}(jQuery));var $mcj = jQuery.noConflict(true);</script>
    <!--End mc_embed_signup-->
    </div>

    <div class="inner">
        <div id="disqus_thread"></div>
    </div>

    
</main>

<div class="t-g-control">
    <div class="gotop">
        <svg class="icon" width="32px" height="32px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M793.024 710.272a32 32 0 1 0 45.952-44.544l-310.304-320a32 32 0 0 0-46.4 0.48l-297.696 320a32 32 0 0 0 46.848 43.584l274.752-295.328 286.848 295.808z" fill="#8a8a8a" /></svg>
    </div>
    <div class="toc-control">
        <svg class="icon toc-icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M779.776 480h-387.2a32 32 0 0 0 0 64h387.2a32 32 0 0 0 0-64M779.776 672h-387.2a32 32 0 0 0 0 64h387.2a32 32 0 0 0 0-64M256 288a32 32 0 1 0 0 64 32 32 0 0 0 0-64M392.576 352h387.2a32 32 0 0 0 0-64h-387.2a32 32 0 0 0 0 64M256 480a32 32 0 1 0 0 64 32 32 0 0 0 0-64M256 672a32 32 0 1 0 0 64 32 32 0 0 0 0-64" fill="#8a8a8a" /></svg>
        <svg class="icon toc-close" style="display: none;" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 960c-247.039484 0-448-200.960516-448-448S264.960516 64 512 64 960 264.960516 960 512 759.039484 960 512 960zM512 128.287273c-211.584464 0-383.712727 172.128262-383.712727 383.712727 0 211.551781 172.128262 383.712727 383.712727 383.712727 211.551781 0 383.712727-172.159226 383.712727-383.712727C895.712727 300.415536 723.551781 128.287273 512 128.287273z" fill="#8a8a8a" /><path d="M557.05545 513.376159l138.367639-136.864185c12.576374-12.416396 12.672705-32.671738 0.25631-45.248112s-32.704421-12.672705-45.248112-0.25631l-138.560301 137.024163-136.447897-136.864185c-12.512727-12.512727-32.735385-12.576374-45.248112-0.063647-12.512727 12.480043-12.54369 32.735385-0.063647 45.248112l136.255235 136.671523-137.376804 135.904314c-12.576374 12.447359-12.672705 32.671738-0.25631 45.248112 6.271845 6.335493 14.496116 9.504099 22.751351 9.504099 8.12794 0 16.25588-3.103239 22.496761-9.247789l137.567746-136.064292 138.687596 139.136568c6.240882 6.271845 14.432469 9.407768 22.65674 9.407768 8.191587 0 16.352211-3.135923 22.591372-9.34412 12.512727-12.480043 12.54369-32.704421 0.063647-45.248112L557.05545 513.376159z" fill="#8a8a8a" /></svg>
    </div>
    <div class="gobottom">
        <svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M231.424 346.208a32 32 0 0 0-46.848 43.584l297.696 320a32 32 0 0 0 46.4 0.48l310.304-320a32 32 0 1 0-45.952-44.544l-286.848 295.808-274.752-295.36z" fill="#8a8a8a" /></svg>
    </div>
</div>
<div class="toc-main" style="right: -100%">
    <div class="post-toc">
        <span>TOC</span>
        <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#一-认证（Authentication）：我是谁"><span class="toc-text">一. 认证（Authentication）：我是谁</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#客户端证书认证"><span class="toc-text">客户端证书认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#静态密码文件认证"><span class="toc-text">静态密码文件认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#静态-Token-文件认证"><span class="toc-text">静态 Token 文件认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Service-Account-Tokens-认证"><span class="toc-text">Service Account Tokens 认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#OpenID-认证"><span class="toc-text">OpenID 认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Webhook-Token-认证"><span class="toc-text">Webhook Token 认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Keystone-认证"><span class="toc-text">Keystone 认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#匿名请求"><span class="toc-text">匿名请求</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#二-授权（Authorization）：我能做什么"><span class="toc-text">二. 授权（Authorization）：我能做什么</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#ABAC（Attribute-Based-Access-Control）"><span class="toc-text">ABAC（Attribute-Based Access Control）</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-Alice-可以做任何事情"><span class="toc-text">1. Alice 可以做任何事情</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-kubelet-可以读取所有-pods-的信息"><span class="toc-text">2. kubelet 可以读取所有 pods 的信息</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-kubelet-可以对-events-进行任何的读写操作"><span class="toc-text">3. kubelet 可以对 events 进行任何的读写操作</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-Bob-可以读取-projectCaribou-namespace-的所有-pods-信息"><span class="toc-text">4. Bob 可以读取 projectCaribou namespace 的所有 pods 信息</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#5-所有人都能对所有路径发送只读请求"><span class="toc-text">5. 所有人都能对所有路径发送只读请求</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RBAC（Role-Based-Access-Control）"><span class="toc-text">RBAC（Role-Based Access Control）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Web-Hook"><span class="toc-text">Web Hook</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#自定义"><span class="toc-text">自定义</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#参考资料"><span class="toc-text">参考资料</span></a></li></ol>
    </div>
</div>



        

<aside class="read-next outer">
    <div class="inner">
        <div class="read-next-feed">
            
            

<article class="read-next-card"  style="background-image: url(https://cizixs-blog.oss-cn-beijing.aliyuncs.com/006tNc79ly1g1qxcn9ft3j318w0txdo6.jpg)"  >
  <header class="read-next-card-header">
    <small class="read-next-card-header-sitetitle">&mdash; Cizixs Write Here &mdash;</small>
    <h3 class="read-next-card-header-title">Recent Posts</h3>
  </header>
  <div class="read-next-divider">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path d="M13 14.5s2 3 5 3 5.5-2.463 5.5-5.5S21 6.5 18 6.5c-5 0-7 11-12 11C2.962 17.5.5 15.037.5 12S3 6.5 6 6.5s4.5 3.5 4.5 3.5"/>
    </svg>
  </div>
  <div class="read-next-card-content">
    <ul>
      
      
      
      <li>
        <a href="/2018/08/26/what-is-istio/">什么是 istio</a>
      </li>
      
      
      
      <li>
        <a href="/2018/08/25/knative-serverless-platform/">serverless 平台 knative 简介</a>
      </li>
      
      
      
      <li>
        <a href="/2018/06/25/kubernetes-resource-management/">kubernetes 资源管理概述</a>
      </li>
      
      
      
      <li>
        <a href="/2018/01/24/use-prometheus-and-grafana-to-monitor-linux-machine/">使用 promethues 和 grafana 监控自己的 linux 机器</a>
      </li>
      
      
      
      <li>
        <a href="/2018/01/13/linux-udp-packet-drop-debug/">linux 系统 UDP 丢包问题分析思路</a>
      </li>
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    </ul>
  </div>
  <footer class="read-next-card-footer">
    <a href="/archives">  MORE  → </a>
  </footer>
</article>


            
            
            
        </div>
    </div>
</aside>


<footer class="site-footer outer">

	<div class="site-footer-content inner">
		<section class="copyright">
			<a href="/" title="Cizixs Write Here">Cizixs Write Here</a>
			&copy; 2019
		</section>
		<nav class="site-footer-nav">
			
            <a href="https://hexo.io" title="Hexo" target="_blank" rel="noopener">Hexo</a>
            <a href="https://github.com/xzhih/hexo-theme-casper" title="Casper" target="_blank" rel="noopener">Casper</a>
        </nav>
    </div>
</footer>






<div class="floating-header" >
	<div class="floating-header-logo">
        <a href="/" title="Cizixs Write Here">
			
                <img src="https://cizixs-blog.oss-cn-beijing.aliyuncs.com/006tNc79ly1g1qxfovpzyj30740743yg.jpg" alt="Cizixs Write Here icon" />
			
            <span>Cizixs Write Here</span>
        </a>
    </div>
    <span class="floating-header-divider">&mdash;</span>
    <div class="floating-header-title">kubernetes 权限管理</div>
    <progress class="progress" value="0">
        <div class="progress-container">
            <span class="progress-bar"></span>
        </div>
    </progress>
</div>
<script>
   $(document).ready(function () {
    var progressBar = document.querySelector('progress');
    var header = document.querySelector('.floating-header');
    var title = document.querySelector('.post-full-title');
    var lastScrollY = window.scrollY;
    var lastWindowHeight = window.innerHeight;
    var lastDocumentHeight = $(document).height();
    var ticking = false;

    function onScroll() {
        lastScrollY = window.scrollY;
        requestTick();
    }
    function requestTick() {
        if (!ticking) {
            requestAnimationFrame(update);
        }
        ticking = true;
    }
    function update() {
        var rect = title.getBoundingClientRect();
        var trigger = rect.top + window.scrollY;
        var triggerOffset = title.offsetHeight + 35;
        var progressMax = lastDocumentHeight - lastWindowHeight;
            // show/hide floating header
            if (lastScrollY >= trigger + triggerOffset) {
                header.classList.add('floating-active');
            } else {
                header.classList.remove('floating-active');
            }
            progressBar.setAttribute('max', progressMax);
            progressBar.setAttribute('value', lastScrollY);
            ticking = false;
        }

        window.addEventListener('scroll', onScroll, {passive: true});
        update();

        // TOC
        var width = $('.toc-main').width();
        $('.toc-control').click(function () {
            if ($('.t-g-control').css('width')=="50px") {
                if ($('.t-g-control').css('right')=="0px") {
                    $('.t-g-control').animate({right: width}, "slow");
                    $('.toc-main').animate({right: 0}, "slow");
                    toc_icon()
                } else {
                    $('.t-g-control').animate({right: 0}, "slow");
                    $('.toc-main').animate({right: -width}, "slow");
                    toc_icon()
                }
            } else {
                if ($('.toc-main').css('right')=="0px") {
                    $('.toc-main').slideToggle("fast", toc_icon());
                } else {
                    $('.toc-main').css('right', '0px');
                    toc_icon()
                }
            }
        })

        function toc_icon() {
            if ($('.toc-icon').css('display')=="none") {
                $('.toc-close').hide();
                $('.toc-icon').show();
            } else {
                $('.toc-icon').hide();
                $('.toc-close').show();
            }
        }

        $('.gotop').click(function(){
            $('html,body').animate({scrollTop:$('.post-full-header').offset().top}, 800);
        });
        $('.gobottom').click(function () {
            $('html,body').animate({scrollTop:$('.pagination').offset().top}, 800);
        });

        // highlight
        // https://highlightjs.org
        $('pre code').each(function(i, block) {
            hljs.highlightBlock(block);
        });
        $('td.code').each(function(i, block) {
            hljs.highlightBlock(block);
        });

        console.log("this theme is from https://github.com/xzhih/hexo-theme-casper")
    });
</script>



<link rel="stylesheet" href="https://cdn.staticfile.org/lightgallery/1.3.9/css/lightgallery.min.css">



<script src="https://cdn.staticfile.org/lightgallery/1.3.9/js/lightgallery.min.js"></script>


<script>
	$(function () {
		var postImg = $('#lightgallery').find('img');
		postImg.addClass('post-img');
		postImg.each(function () {
			var imgSrc = $(this).attr('src');
			$(this).attr('data-src', imgSrc);
		});
		$('#lightgallery').lightGallery({selector: '.post-img'});
	});
</script>



<script>

/**
*  RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
*  LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/

var disqus_config = function () {
this.page.url = 'http://cizixs.com/2017/06/16/kubernetes-authentication-and-authorization/';  // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = 'http://cizixs.com/2017/06/16/kubernetes-authentication-and-authorization/'; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};

(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = 'https://cizixs.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
                            


    </div>
</body>
</html>
